﻿using System;
using PMS.XCMG.Entity;
using PMS.XCMG.IBusiness;
using PMS.XCMG.Models;
using PMS.XCMG.Util;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;

namespace PMS.XCMG.Api.Controllers
{
    /// <summary>
    /// Plan
    /// </summary>
    public class PlanController : BaseController
    {
        /// <summary>
        /// 
        /// </summary>
        public IPlanBusiness Bus { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public IServiceProvider SvcProvider { get; set; }


        /// <summary>
        /// 
        /// </summary>
        public IPrecollectedBusiness PCBus { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public IPlanPrepareBusiness preBus { set; get; }

        /// <summary>
        /// 
        /// </summary>
        public IMaterialBomTreeBusiness BtBus { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bus"></param>
        /// <param name="pcbus"></param>
        /// <param name="_preBus"></param>
        /// <param name="btbus"></param>
        /// <param name="svcProvider"></param>
        public PlanController(IPlanBusiness bus, IPrecollectedBusiness pcbus, IPlanPrepareBusiness _preBus, IMaterialBomTreeBusiness btbus, IServiceProvider svcProvider)
        {
            this.Bus = bus;
            this.PCBus = pcbus;
            this.BtBus = btbus;
            this.preBus = _preBus;

            this.SvcProvider = svcProvider;
        }

        /// <summary>
        /// 获取单个实体
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpGet]
        public Task<Plan> GetAsync(string id)
        {
            return this.Bus.GetAsync(id, true);
        }

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <returns></returns>
        [HttpPost]
        public Task<PageResult<Plan>> GetPageAsync(PageInput<PlanQM> query)
        {
            return this.Bus.GetPageResultAsync(query);
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="data">对应数据</param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public async Task<int> SaveAsync(Plan data)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(data.Id))
                {
                    this.InitBusEntity(data);

                    var db = SvcProvider.GetRequiredService<GDbContext>();
                    var bom = await db.MaterialBom.AsQueryable().Include(i => i.Spec).Where(p => p.Id == data.BomId).FirstOrDefaultAsync();
                    data.Code = bom.Spec.MesCode;
                    data.Name = bom.Spec.Code;

                    var date = Convert.ToDateTime(data.PlanDate);
                    data.PlanDate = date.ToString("yyyy-MM-dd");
                    data.PlanDay = Convert.ToInt32(date.ToString("yyyyMMdd"));

                    await db.Plan.AddAsync(data);

                    var bomTrees = await db.MaterialBomTree.AsQueryable()
                            .Include(i => i.Materiel)
                            .Include(i => i.Spec)
                            .Where(p => p.BomId == bom.Id && p.HasChild == false)
                            .ToListAsync();

                    foreach (var item in bomTrees)
                    {
                        await db.Precollected.AddAsync(new Precollected()
                        {
                            Id = Guid.NewGuid().ToString("n"),
                            PlanId = data.Id,
                            BomTreeId = item.Id,
                            MaterielId = item.MaterialId,
                            MaterieCode = item.Materiel.Code,
                            MaterieName = item.Materiel.Name,
                            SpecId = item.SpecId,
                            SpecCode = item.Spec.Code,
                            SpecName = item.Spec.Name,
                            Quantity = item.Quantity * data.Count,
                            RealIncome = 0,
                            CreateTime = DateTime.Now,
                            CreateUserId = "1",
                            ModifyTime = DateTime.Now,
                            ModifyUserId = "1",
                            Deleted = false
                        });

                        await db.PlanPrepare.AddAsync(new PlanPrepare()
                        {
                            Id = Guid.NewGuid().ToString("n"),
                            PlanId = data.Id,
                            BomTreeId = item.Id,
                            MaterielId = item.MaterialId,
                            EleCode = item.Materiel.Code,
                            Name = item.Materiel.Name,
                            SpecName = item.Spec.Name,
                            Count = item.Quantity * data.Count,
                            Quantity = 0,
                            DeliveryCount = 0,
                            CreateTime = DateTime.Now,
                            CreateUserId = "1",
                            ModifyTime = DateTime.Now,
                            ModifyUserId = "1",
                            Deleted = false
                        });
                    }

                    db.SaveChanges();
                }
                else
                {
                    data.ModifyTime = DateTime.Now;
                    data.ModifyUserId = "1";
                    await this.Bus.UpdateAsync(data);
                }
            }
            catch (Exception ex)
            {

            }

            return 1;
        }

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="ids">数据主键</param>
        /// <returns></returns>
        [HttpDelete]
        [Transaction]
        public Task<int> DeleteAsync(List<string> ids)
        {
            return this.Bus.DeleteAsync(ids);
        }

        /// <summary>
        /// 计划下发
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public async Task<int> PlanIssueAsync(Plan data)
        {
            if (data == null) throw new Exception("未识别有效参数");
            var db = SvcProvider.GetRequiredService<GDbContext>();
            try
            {
                //Bom数据
                var bom = await db.MaterialBom.AsQueryable<MaterialBom>().FirstOrDefaultAsync(t => !t.Deleted && t.Id == data.BomId);

                //按订单编号下发的配置数据
                var order = await db.WorkshoStationSetting.AsQueryable<WorkshoStationSetting>().Include(t => t.Station).Where(t => !t.Deleted && t.SettingType == "Order" && t.SettingItem == "OrderAddress")
                   .ToListAsync();

                //按物料编号下发配置数据
                var meter = await db.WorkshoStationSetting.AsQueryable<WorkshoStationSetting>().Where(t => !t.Deleted && t.SettingType == "Order" && t.SettingItem == "MeterAddress")
                    .Include(t => t.Station).ToListAsync();

                //按订单数量下发的配置数据
                var quantity = await db.WorkshoStationSetting.AsQueryable<WorkshoStationSetting>().Where(t => !t.Deleted && t.SettingType == "Order" && t.SettingItem == "QuantityAddress")
                     .Include(t => t.Station).ToListAsync();
                 
                var plcAssignList = new List<PlcAssign>();

                //订单编号下发
                order.ForEach(t =>
                {
                    plcAssignList.Add(new PlcAssign
                    {
                        Id = Guid.NewGuid().ToString("n"),
                        Type = "CusAssign",
                        Status = "Active",
                        LogAddr = t.SettingValue,
                        Group = t.GroupCode,
                        Name = $@"{t.Station.Name}订单编号下发",
                        Seq = 1,
                        Value = data.Code,
                        CreateTime = DateTime.Now,
                        CreateUserId = "1",
                        Deleted = false,
                        RefTable = "Plan",
                        RefId = data.Id
                    });
                });
                //订单物料下发
                meter.ForEach(t =>
                {
                    plcAssignList.Add(new PlcAssign
                    {
                        Id = Guid.NewGuid().ToString("n"),
                        Type = "CusAssign",
                        Status = "Active",
                        LogAddr = t.SettingValue,
                        Group = t.GroupCode,
                        Name = $@"{t.Station.Name}订单物料编号下发",
                        Seq = 2,
                        Value = bom.EleCode,
                        CreateTime = DateTime.Now,
                        CreateUserId = "1",
                        Deleted = false,
                        RefTable = "Plan",
                        RefId = data.Id
                    });
                });
                //订单数量下发
                quantity.ForEach(t =>
                {
                    plcAssignList.Add(new PlcAssign
                    {
                        Id = Guid.NewGuid().ToString("n"),
                        Type = "CusAssign",
                        Status = "Active",
                        LogAddr = t.SettingValue,
                        Group = t.GroupCode,
                        Name = $@"{t.Station.Name}订单数量下发",
                        Seq = 3,
                        Value = data.Count.ToString(),
                        CreateTime = DateTime.Now,
                        CreateUserId = "1",
                        Deleted = false,
                        RefTable = "Plan",
                        RefId = data.Id
                    });
                });
                await db.AddRangeAsync(plcAssignList);

                await db.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return 1;
        }

        /// <summary>
        /// 撤回计划下发
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpDelete]
        [Transaction]
        public async Task<int> RollBackPlanIssueAsync(string Id)
        {
            if (string.IsNullOrWhiteSpace(Id)) throw new Exception("请选择有效的数据");
            var db = SvcProvider.GetRequiredService<GDbContext>();

            var PlcAssignList = await db.Set<PlcAssign>().AsQueryable().Where(t => t.RefId == Id).ToListAsync();
            db.RemoveRange(PlcAssignList);

            await db.SaveChangesAsync();

            return 1; 
        }
    }
}
